package com.wsoft.hr.pm.util;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wsoft.hr.pm.enums.FormulaTypeEnum;
import com.wsoft.hr.pm.enums.TargetTypeEnum;
import com.wsoft.hr.pm.query.target.CalculateScoreQuery;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 指标公式计算util
 * @Author z001
 * @Date 2025/3/4 17:02
 */
public class TargetCalculateScoreUtil {

    public static void main(String[] args) {
    	CalculateScoreQuery entity = new CalculateScoreQuery();
        entity.setFormulaType("formula_percent");
        entity.setFormulaValue("[{\"sign\":\"0\",\"score\":\"30\",\"percentage\":\"50\"},{\"sign\":\"3\",\"percentage\":\"50\",\"score\":\"20\"},{\"sign\":\"5\",\"percentage\":\"50\",\"score\":\"10\"}]");
        entity.setPurposeValue(new BigDecimal(60));
        entity.setWeight(new BigDecimal(20));
        entity.setTargetType(TargetTypeEnum.OUT_REFERENCE_ADD.getType());
        entity.setResultValue(new BigDecimal(31));
        System.out.println(calculateScore(entity));
    }

    /**
     * 计算得分
     * @param entity
     * @param score
     * @return
     */
    public static BigDecimal calculateScore(CalculateScoreQuery entity){
        if(null == entity || StrUtil.isEmpty(entity.getFormulaType()) || StrUtil.isEmpty(entity.getFormulaValue())){
            return BigDecimal.ZERO;
        }
        if(FormulaTypeEnum.FORMULA_DIRECT.getType().equals(entity.getFormulaType())){
            //直接计分
            return calculateDirectScore(entity.getTargetType(),entity.getFormulaValue(),entity.getResultValue(),entity.getPurposeValue(),entity.getWeight());
        }else{
//            百分比计分
            return calculatePercentageScore(entity.getTargetType(),entity.getFormulaValue(),entity.getResultValue(),entity.getPurposeValue(),entity.getWeight());
        }
    }

    /**
     * 计算百分比得分
     *
     * @param formula     百分比计算公式的 JSON 数组字符串
     * @param resultValue 结果值
     * @return 计算后的得分
     */
    private static BigDecimal calculatePercentageScore(String targetType,String formula, BigDecimal resultValue,BigDecimal purposeValue,BigDecimal weight) {
        try {
            JSONArray formulaArray = JSONArray.parseArray(formula);
            return TargetTypeEnum.REFERENCE.getType().equals(targetType)?calculatePercentageScore(formulaArray, resultValue,purposeValue):calculatePercentageScore(formulaArray, resultValue,purposeValue).multiply(weight).divide(new BigDecimal("100"), 0, RoundingMode.HALF_UP);
        } catch (Exception e) {
            e.printStackTrace();
            //默认返回0
            return BigDecimal.ZERO;
        }
    }

    /**
     * 计算直接得分
     *
     * @param formula     直接计算公式的 JSON 数组字符串
     * @param resultValue 结果值
     * @return 计算后的得分
     */
    private static BigDecimal calculateDirectScore(String targetType , String formula, BigDecimal resultValue,BigDecimal purposeValue,BigDecimal weight) {
        try {
            JSONArray formulaArray = JSONArray.parseArray(formula);
            return TargetTypeEnum.REFERENCE.getType().equals(targetType)?calculateDirectScore(formulaArray, resultValue,purposeValue):calculateDirectScore(formulaArray, resultValue,purposeValue).multiply(weight).divide(new BigDecimal("100"), 0, RoundingMode.HALF_UP);
        } catch (Exception e) {
            e.printStackTrace();
            // 返回默认值 0
            return BigDecimal.ZERO;
        }
    }

    private static BigDecimal calculatePercentageScore(JSONArray formulaArray, BigDecimal resultValue,BigDecimal purposeValue) {
        BigDecimal score = BigDecimal.ZERO;

        for (int i = 0; i < formulaArray.size(); i++) {
            JSONObject rule = formulaArray.getJSONObject(i);
            int sign = rule.getIntValue("sign");
            // 百分比
            BigDecimal percentage = new BigDecimal(rule.getString("percentage"));
            // 得分
            BigDecimal ruleScore = new BigDecimal(rule.getString("score"));

            // 计算目标百分比值：TARGET_VALUE * (percentage / 100)
            BigDecimal targetPercentageValue = purposeValue
                    .multiply(percentage)
                    // 保留两位小数
                    .divide(new BigDecimal("100"), 0, RoundingMode.HALF_UP);

            if (compare(resultValue, sign, targetPercentageValue)) {
                score = ruleScore;
                break; // 找到第一个匹配的规则后退出
            }
        }

        return score;
    }

    private static BigDecimal calculateDirectScore(JSONArray formulaArray, BigDecimal resultValue,BigDecimal purposeValue) {
        BigDecimal score = BigDecimal.ZERO;

        for (int i = 0; i < formulaArray.size(); i++) {
            JSONObject rule = formulaArray.getJSONObject(i);
            int sign = rule.getIntValue("sign");
            // 得分
            BigDecimal ruleScore = new BigDecimal(rule.getString("score"));

            if (compare(resultValue, sign, purposeValue)) {
                score = ruleScore;
                break; // 找到第一个匹配的规则后退出
            }
        }

        return score;
    }

    private static boolean compare(BigDecimal resultValue, int sign, BigDecimal targetValue) {
        switch (sign) {
            case 0:
                return resultValue.compareTo(targetValue) == 0;
            case 1:
                return resultValue.compareTo(targetValue) != 0;
            case 2:
                return resultValue.compareTo(targetValue) >= 0;
            case 3:
                return resultValue.compareTo(targetValue) > 0;
            case 4:
                return resultValue.compareTo(targetValue) <= 0;
            case 5:
                return resultValue.compareTo(targetValue) < 0;
            default:
                throw new IllegalArgumentException("Invalid sign value: " + sign);
        }
    }

}
